#include "discidentifier.h"
#include <QProcess>
#include <windows.h>

DiscIdentifier::DiscIdentifier(QObject *parent) :
    QObject(parent)
{
    _dvdStatus = IDENTIFIYING;
}

DiscIdentifier::DiscIdentifier(const QString drive, QObject *parent):
    QObject(parent),_driveLetter(drive),_newDriveLetter(drive)
{
    _dvdStatus = IDENTIFIYING;

}
DiscIdentifier::DiscIdentifier(const char * drive, QObject *parent ):
    QObject(parent)
{
    _driveLetter = QString(drive);
    _newDriveLetter = _driveLetter;
    _dvdStatus = IDENTIFIYING;
}

DiscIdentifier::MediaType DiscIdentifier::getMediaType()
{
    qDebug()<<"DiscIdentifier::MediaType DiscIdentifier::getMediaType()";
    Logger::log()<<"DiscIdentifier::MediaType DiscIdentifier::getMediaType()";
    if(!this->_driveLetter.contains(':'))
        this->_driveLetter +=":";
    qDebug()<<"look for: "<<this->_driveLetter+"/ANY!/Unit_Key_RO.inf";
    Logger::log()<<"look for: "<<this->_driveLetter+"/ANY!/Unit_Key_RO.inf";
    QFile file(this->_driveLetter+"/ANY!/Unit_Key_RO.inf");
    if(file.exists())
    {
        return BLURAY;
    }
    qDebug()<<"look for: "<<this->_driveLetter+"/VIDEO_TS/VIDEO_TS.IFO";
    Logger::log()<<"look for: "<<this->_driveLetter+"/VIDEO_TS/VIDEO_TS.IFO";
    QFile fileDVD(this->_driveLetter+"/VIDEO_TS/VIDEO_TS.IFO");
    if(fileDVD.exists())
    {
        return DVD;
    }
    return CD;
}

void DiscIdentifier::identify()
{
    _driveLetter = _newDriveLetter;
    MediaType mediaType =getMediaType();
    switch(mediaType)
    {
    case BLURAY:
        identifyBLURAY();
        break;
    case DVD:
        identifyDVD();
        break;
    case CD:
        identifyCD();
        break;
    default:
        qDebug()<<"Undefined media type, value: "<<mediaType;
        break;
    }
    return;
}

void DiscIdentifier::identifyBLURAY()
{
    qDebug()<<"void DiscIdentifier::identifyBLURAY()";
    if(!this->_driveLetter.contains(':'))
        this->_driveLetter +=":";
    QFile file(this->_driveLetter+"/ANY!/Unit_Key_RO.inf");
    if(file.exists())
    {
        qDebug()<<"BLURAY - opening: "<<this->_driveLetter+"/ANY!/Unit_Key_RO.inf";

        if (file.open(QIODevice::ReadOnly))
        {
            QByteArray hash = QCryptographicHash::hash(file.readAll(), QCryptographicHash::Sha1);
            QByteArray discId = hash.toHex();
            qDebug()<<"Disc Id: "<<discId;
            file.close();
            if(!discId.isEmpty())
            {
                qDebug()<<"Emiting signal discIdentified: "<<discId;
                emit discIdentified(discId);
            }
        }
    }
}

void DiscIdentifier::identifyDVD()
{
    qDebug()<<"void DiscIdentifier::identifyDVD()";
    qDebug()<<"_dvdStatus: "<<_dvdStatus;
    Logger::log()<<"void DiscIdentifier::identifyDVD()";
    Logger::log()<<"_dvdStatus: "<<_dvdStatus;
    switch(_dvdStatus)
    {
    case IDENTIFIYING:
    {
        QProcess process;
        process.start("C:/AnyTool.exe", QStringList() << "-d");
        Logger::log()<<"C:/AnyTool.exe -d";
        if(process.waitForFinished( ))
        {
            qDebug()<<"AnyTool.exe -d success";
            Logger::log()<<"AnyTool.exe -d success";
            Sleep(uint(2000));
        }
        else
        {
            qDebug()<<"AnyTool.exe -d ERROR";
            Logger::log()<<"AnyTool.exe -d ERROR";
        }
        _dvdStatus = WAITING_ANYDVD_DISABLED;
        emit reloadDisc();
        break;
    }
    case WAITING_ANYDVD_DISABLED:
    {
        QFile fileDVD(this->_driveLetter+"/VIDEO_TS/VIDEO_TS.IFO");
        if(fileDVD.exists())
        {
            uint64_t dvdid;
            dvdid_status_t i;
            int e;

            Logger::log()<<"dvdid_calculate";
            qDebug()<<"dvdid_calculate";
            i = dvdid_calculate(&dvdid, this->_driveLetter.toStdString().c_str(), &e);

            qDebug()<<"dvdid_calculate result: "<<i;
            Logger::log()<<"dvdid_calculate result: "<<i;

            switch(i)
            {
              case (DVDID_STATUS_OK):
                char msg[100];
                sprintf(msg, "%08" "x" "-%08" "x", (uint32_t) (dvdid >> 32), (uint32_t) dvdid);
                _dvdid = msg;
                //fprintf(stdout, "x%08 -%08\n" , (uint32_t) (dvdid >> 32), (uint32_t) dvdid);
                qDebug()<<"dvdid: "<<msg;
                //return 0;
                Logger::log()<<"dvdid: "<<msg;
            }
        }
        QProcess process;
        process.start("C:/AnyTool.exe", QStringList() << "-e");
        Logger::log()<<"C:/AnyTool.exe -e";
        if(process.waitForFinished( ))
        {
            Logger::log()<<"AnyTool.exe -e success";
            qDebug()<<"AnyTool.exe -e success";
        }
        else
        {
            Logger::log()<<"AnyTool.exe -e ERROR";
            qDebug()<<"AnyTool.exe -e ERROR";
        }
        emit reloadDisc();
        _dvdStatus = WAITING_ANYDVD_ENABLED;
        break;
    }
    case WAITING_ANYDVD_ENABLED:
        qDebug()<<"Emiting signal discIdentified: "<<_dvdid;
        Logger::log()<<"Emiting signal discIdentified: "<<_dvdid;
        emit discIdentified(_dvdid);
        _dvdStatus = IDENTIFIYING;
        break;
    default:
        qDebug()<<"UNKNOWN STATUS: "<<_dvdStatus;
    }

}

void DiscIdentifier::identifyCD()
{
    qDebug()<<"DiscIdentifier::identifyCD()";

}
void DiscIdentifier::changeLetter(QString newLetter)
{
    _newDriveLetter = newLetter;
}

